import { Button, ImageViewer, Mask, Modal, Space, Toast } from "antd-mobile";
import React, { useEffect, useRef, useState } from "react";
import { useRouter } from "next/router"
import dynamic from "next/dynamic";
import { isValidArr, navigateTo, randomBetween } from "@/utils";
import callFeedback from "@/components/common/modalFeedback";
import requewt from "@/utils/requewt";
import { API, BASE_PATH } from "@/config";
import classnames from "classnames";
import { CardContentComp } from "@/components/pages/game/self";

const Sketch = dynamic(() => import("react-p5").then((mod) => {

  // importing sound lib only after react-p5 is loaded
  require('../../../../../libs/p5.sound.min.js')
  require('../../../../../libs/p5.collide2d.js')
  // import ('../../../../../libs/planck.min.js')
  // import ('../../../../../libs/p5play.min.js')

  // returning react-p5 default export
  return mod.default
}), {
  ssr: false
});
// import Sketch from 'react-p5';
// import '@/libs/p5.sound.min.js';
// import '@/libs/planck.min.js';
// import '@/libs/p5play.js';
// import 'p5play/planck.min.js';
// import 'p5play/p5play.min.js';


import useApp from "@/stores/useApp";
import { create } from "zustand";

let doodlerSize = 100;
let doodlerSizeX = 80;
let doodlerX;
let doodlerY;
let doodlerVelocity;
let doodlerXSpeed = 4;
let platformWidth = 120;
let itemWidth = 60;
let itemHeight = 60;
let platformHeight = 25;
let numOfPlatforms = 5;
let hardScore = 1000;
let emptyChance = .5;
let textList = [];
let platformList = [];
let itemList = [];
let platYChange = 0;
let gameStarted = false;
let end = true;
let score = 0;
let highScore = 0;
let doodlerLeftImg;
let doodlerRightImg;
let platformImg;
let backgroundImg;
let boardImg;
let itemImg_1;
let itemImg_2;
let itemImg_3;
let itemImg_4;
let guideImg;

let audio_bgm;
let audio_end;
let audio_item;
let audio_jump;
let audio_rock;
let jumping = false;

let selectedTimes;

let img_guide = undefined;

// resources
let font = undefined;
let spirit_timer = {
  src: undefined,
  width: 120,
  height: 32
};
let spirit_score = {
  src: undefined,
  width: 120,
  height: 32
};
let spirit_basket = {
  src: undefined,
  spirit: undefined,
  flag: -1,
  width: 50,
  height: 50
};

let spirit_basket_right = {
  src: undefined,
  spirit: undefined,
  flag: 1,
  width: 50,
  height: 50
};
let spirit_ground = {
  src: undefined,
  width: 0,
  height: 0
};
let spirit_battery = {
  src: undefined,
  width: 260,
  height: 40
};
let spirit_bg = {
  src: undefined,
  width: 0,
  height: 0
};

let spirit_ball = {
  src: undefined,
  spirit: undefined,
  angle: 0,
  width: 50,
  height: 50
};

// system
let game_start = false;
let fps = 60;
// 游戏计时时间
let game_time_max = 30;
// 当前的时间
let game_time_current = 0;
// 当前的分数
let game_score = 0;
// 高亮的分数
let game_score_highlight = 500;
// 获胜的分数
let game_score_win = 500;
// 左右的flag 默认是左边
let game_direction_flag = -1;
let game_direction_vol = -2;
let jumps = [];
let free_time = 0;

let basket_pos = 0;

let spring = 0.05;
let gravity_origin = 0.3;
let gravity = gravity_origin;
let friction = -0.2;

let elements = [];
let scores = [];
let scoring = 1000;

let baskets = []

let current_vy = 0;
let angle = 0;
let released = true;

let basketball = undefined;

export default function ({}) {

  const router = useRouter();
  const [id, setID] = useState(undefined);
  const [error, setErr] = useState(undefined);
  const [checked, setChecked] = useState(undefined);
  const [open, setOpen] = useState(undefined);
  const [cards, setCards] = useState(undefined);
  const [selected, setSelected] = useState(undefined);
  const [visible, setVisible] = useState(undefined);
  const env = useApp(state => state.env);


  let height = window.innerHeight;
  let width = window.innerWidth;

  const ITEM_MAP = {
    1: {
      img: itemImg_1,
      score: 5,
      audio: `https://yinli-qixi-run.varwey.com/2023/3w-jump-alien-230703/audio/ae-item.mp3`
    },
    2: {
      img: itemImg_2,
      score: 10,
      audio: `https://yinli-qixi-run.varwey.com/2023/3w-jump-alien-230703/audio/ae-item.mp3`
    },
    3: {
      img: itemImg_3,
      score: 15,
      audio: `https://yinli-qixi-run.varwey.com/2023/3w-jump-alien-230703/audio/ae-item.mp3`
    },
    4: {
      img: itemImg_4,
      score: -10,
      audio: `https://yinli-qixi-run.varwey.com/2023/3w-jump-alien-230703/audio/ae-rock.mp3`
    }
  }

  // 预载游戏资源
  const preload = (p5) => {
    backgroundImg = p5.loadImage(`${BASE_PATH}/img/kv/kv-bg-sec.jpg`);
    guideImg = p5.loadImage(`${BASE_PATH}/img/game/game-guide-3.png`);
    img_guide = p5.loadImage(`${BASE_PATH}/img/game/game-guide.jpg`);

    font = p5.loadFont(`https://yinli-qixi-run.varwey.com/changan-uni-regular.ttf`)

    spirit_battery.src = p5.loadImage(`${BASE_PATH}/img/game/game-battery-underlay.png`);
    spirit_basket.src = p5.loadImage(`${BASE_PATH}/img/game/game-basket-group.png`);
    spirit_bg.src = p5.loadImage(`${BASE_PATH}/img/game/game-bg-left.jpg`);
    spirit_ground.src = p5.loadImage(`${BASE_PATH}/img/game/game-bg-left.jpg`);
    spirit_score.src = p5.loadImage(`${BASE_PATH}/img/game/game-score.png`);
    spirit_timer.src = p5.loadImage(`${BASE_PATH}/img/game/game-timer.png`);
    spirit_ball.src = p5.loadImage(`${BASE_PATH}/img/game/game-ball.png`);


    p5.soundFormats('mp3');
    audio_bgm = p5.loadSound(`${BASE_PATH}/audio/ae-bgm.mp3`);
    audio_bgm.setVolume(0.3);
    audio_bgm.setLoop(true);
    audio_end = p5.loadSound(`${BASE_PATH}/audio/ae-end.mp3`);
    audio_end.setVolume(0.5);

  }

  // 装载游戏
  const setup = (p5, canvasParentRef) => {
    p5.frameRate(fps);
    p5.createCanvas(window.innerWidth, window.innerHeight).parent(canvasParentRef);

    p5.imageMode(p5.CENTER);
    p5.angleMode(p5.DEGREES);

    drawEle.ball(p5);
    drawEle.basket(p5);
    drawEle.basket_right(p5);
    basketball = new BasketBall(p5, 0, 0, spirit_ball.width)

  };

  // 绘制游戏
  const draw = (p5) => {

    // if (game_time_current >= game_time_max) {
    //   game_start = false;
    // }

    p5.background(`#c9e3ff`);
    // p5.image(backgroundImg, 0, 0, width, height);
    if (game_start === true) {
      //Set up and draw the game
      // if (dy) gravity = p5.createVector(0, -1);
      // else gravity = p5.createVector(0, 0.5);

      if (p5.mouseIsPressed) {
        // basketball.clearForce()
        // let anti_gravity = p5.createVector(0, -1);
        // basketball.applyForce(anti_gravity);
      }
      // gravity = p5.createVector(0, 0.1);
      // basketball.applyForce(gravity);
      // basketball.update(p5);
      // basketball.edges(p5);
      // basketball.show(p5);

      drawEle.ground(p5);
      drawEle.timer(p5);
      drawEle.score(p5);
      drawEle.battery(p5);

      let dy = jumps.pop() || 0;

      // spirit_ball.spirit.collide(p5)
      spirit_ball.spirit.collide2(p5)
      spirit_ball.spirit.move(p5, game_direction_vol, dy);
      spirit_ball.spirit.display(p5);

      if (game_direction_flag > 0) {
        spirit_basket_right.spirit.display(p5);
      } else {
        spirit_basket.spirit.display(p5);
      }

    } else {
      console.log(222)
      // Start menu
      // Toast.show({content: 1})
      p5.fill(`#f00`);
      p5.image(img_guide, width / 2, height / 2, width, height);
      // p5.fill(0);
      // p5.textSize(32);
      // p5.text("轻触开始", 140, 275);
    }
  };

  // 点击事件捕获
  const mousePressed = (p5) => {
    if (!released) {
      return;
    }
    released = false;

    if (!game_start) {
      initGame()
      return
    }
    console.log(`mousePressed`)

    if (game_direction_flag > 0) game_direction_vol = 2
    else game_direction_vol = -2
    // if (!isValidArr(jumps)) jumps.push(Math.abs(current_vy) < 6 ? -5 : -current_vy);
    if (!isValidArr(jumps)) jumps.push(-10);
    // free_time = 0.5;
  }

  const mouseReleased = (p5) => {
    gravity = gravity_origin;
    released = true;
    // gravity = p5.createVector(0, 1);
    return false;
  }

  // 初始化游戏 包括音乐 分数等
  const initGame = () => {
    console.log(`initGame`)
    game_start = true;
    game_time_current = 0
  }

  // 绘制元素
  const drawEle = {
    ground: p5 => {
      p5.image(
        spirit_ground.src,
        p5.width / 2,
        p5.height - (p5.width / 3 / 2) - spirit_battery.height * 2,
        p5.width,
        p5.width / 3,
      );
    },
    timer: p5 => {
      p5.image(
        spirit_timer.src,
        p5.width / 4 * 1,
        36 + spirit_timer.height / 2,
        spirit_timer.width,
        spirit_timer.height,
      );
      game_time_current += p5.deltaTime / 1000
      p5.fill(255);
      p5.textFont(font);
      p5.textSize(14);
      p5.text("时间：" + game_time_current.toFixed(2), 74, 59);
    },
    score: p5 => {
      p5.image(
        spirit_score.src,
        p5.width / 4 * 3,
        36 + spirit_score.height / 2,
        spirit_score.width,
        spirit_score.height,
      );

      p5.fill(255);
      p5.textFont(font);
      p5.textSize(14);
      p5.text("得分：" + game_score, p5.width / 2 + 74, 59);
    },
    ball: p5 => {
      spirit_ball.spirit = new Ball(p5.width / 2, p5.height / 2, spirit_ball.width, 1, elements);
    },
    basket: p5 => {
      basket_pos = p5.random(p5.height / 3, p5.height / 3 * 2);
      spirit_basket.spirit = new Basket(0, basket_pos, 50, 50);
      baskets.push(spirit_basket);
    },
    basket_right: p5 => {
      basket_pos = p5.random(p5.height / 3, p5.height / 3 * 2);

      spirit_basket_right.spirit = new Basket(p5.width - 50, basket_pos, 50, 50);

      baskets.push(spirit_basket_right);

    },
    battery: p5 => {
      p5.image(
        spirit_battery.src,
        (p5.width) / 2,
        p5.height - (spirit_battery.height),
        spirit_battery.width,
        spirit_battery.height,
      );
    }
  }

  useEffect(() => {
    (async () => {
    })()

    return () => {
      Modal.clear();
      Toast.clear();
    }
  }, [])

  const handler = {
    check: async () => {

    },
    start: async () => {

    },
    finish: async () => {

    },
  }

  return (
    <>
      <div className="App">
        <Sketch setup={setup}
                draw={draw}
                preload={preload}
                mousePressed={mousePressed}
                mouseReleased={mouseReleased}
        />
      </div>

      <Mask visible={open === `guide`} onMaskClick={setOpen}>
        <div className="guide-wrapper">
          <div className="inner">
            <img className="guide-img" src={`${BASE_PATH}/img/game/game-guide.png`}
                 alt="" />
            <Button className={`act-btn act-btn-bevel`} onClick={async () => {
              await handler.start();
            }}>确定</Button>
          </div>
        </div>
      </Mask>

      <Modal visible={visible === `stuff`} onClose={setVisible}
             bodyClassName={`act-feedback-modal cp-game-stuff close-hidden close-at-center-bottom`}
             content={<CardContentComp handler={handler}
                                       selected={selected}
                                       cards={cards} />
             } />
    </>
  )
}

class BasketBall {
  constructor(p5, x, y, r, m) {
    this.pos = p5.createVector(x, y);
    this.vel = p5.createVector(1, -1);
    // this.vel = p5.createVector(0, 0);
    this.acc = p5.createVector(0, 0);
    this.r = r;
  }

  applyForce(force) {
    this.acc.add(force)
  }

  clearForce() {
    this.vel.y *= -0.9;

    // this.acc.set(0, 0);
    // this.vel.set(0, 0);
  }

  edges(p5) {
    if (this.pos.y > p5.height - this.r) {
      this.vel.y *= -0.9;
      this.pos.y = p5.height - this.r;
      // this.vel.y *= -1;
    }

    if (this.pos.x < -this.r) {
      this.pos.x = p5.width;
    } else if (this.pos.x > p5.width) {
      this.pos.x = -this.r;
    }
  }

  update() {
    this.vel.add(this.acc);
    this.pos.add(this.vel);
    this.acc.set(0, 0);
  }

  show(p5) {
    p5.image(
      spirit_ball.src,
      this.pos.x, this.pos.y,
      spirit_ball.width,
      spirit_ball.height,
    );
  }
}

class Ball {
  constructor(xin, yin, din, idin, oin) {
    this.x = xin;
    this.y = yin;
    this.vx = 0;
    this.vy = 0;
    this.diameter = din;
    this.id = idin;
    this.others = oin;
  }

  collide(p5) {
    let oRight = spirit_basket.spirit.x + spirit_basket.spirit.width;
    let oLeft = spirit_basket.spirit.x;
    let oTop = spirit_basket.spirit.y;
    let oBottom = spirit_basket.spirit.y + spirit_basket.spirit.height;
    // console.log(oTop, oRight, oBottom, oLeft,)
    // console.log(this.x, this.y, this.diameter)


    if (
      this.x + this.diameter > oLeft - 10 &&
      this.x + this.diameter < oRight + 10 &&
      this.y + this.diameter > oTop &&
      this.y + this.diameter < oBottom
    ) {
      this.vx = 0;
      this.x = 0;

      if (scoring < 1000) return;
      scoring -= p5.deltaTime
      console.log("collide")
      game_direction_flag = game_direction_flag * -1;
      game_direction_vol = 0;
      basket_pos = p5.random(p5.height / 3, p5.height / 3 * 2);
      game_score += 1;
      return
      // this.vy = 0;
    } else {
      if (scoring < 0) scoring = 1000;
      let dx = spirit_basket.spirit.x - this.x;
      let dy = spirit_basket.spirit.y - this.y;
      let distance = p5.sqrt(dx * dx + dy * dy);
      let minDist = spirit_basket.spirit.width / 2 + this.diameter / 2;

      if (distance < minDist) {
        let angle = p5.atan2(dy, dx);
        let targetX = this.x + p5.cos(angle) * minDist;
        let targetY = this.y + p5.sin(angle) * minDist;
        let ax = (targetX - spirit_basket.spirit.x) * spring;
        let ay = (targetY - spirit_basket.spirit.y) * spring;
        this.vx -= ax;
        this.vy -= ay;
      }
    }


    // for (let i = 0; i < elements.length; i++) {
    //   let dx = this.others[i].x - this.x;
    //   let dy = this.others[i].y - this.y;
    //   let distance = p5.sqrt(dx * dx + dy * dy);
    //   let minDist = this.others[i].diameter + this.diameter / 2;
    //   //   console.log(distance);
    //   //console.log(minDist);
    //   if (distance < minDist) {
    //     //console.log("2");
    //     let angle = p5.atan2(dy, dx);
    //     let targetX = this.x + p5.cos(angle) * minDist;
    //     let targetY = this.y + p5.sin(angle) * minDist;
    //     let ax = (targetX - this.others[i].x) * spring;
    //     let ay = (targetY - this.others[i].y) * spring;
    //     // if (dy) this.vx = 0;
    //     this.vx -= ax;
    //     this.vy -= ay;
    //     this.others[i].vx += ax;
    //     this.others[i].vy += ay;
    //   }
    // }
  }

  collide2(p5) {
    let spirit = baskets.find(e => e.flag === game_direction_flag).spirit;

    // console.log(`spirit`, spirit)

    let oRight = spirit.x + spirit.width;
    let oLeft = spirit.x;
    let oTop = spirit.y;
    let oBottom = spirit.y + spirit.height;

    let hint = p5.collideRectCircle(spirit.x, spirit.y, spirit.width, spirit.height, this.x, this.y, this.diameter)

    console.log(`hint`, hint)

    if (
      hint
    ) {
      this.vx = 0;
      if (game_direction_flag > 0) this.x = p5.width - this.diameter;
      else this.x = 0;

      // if (scoring < 1000) return;
      // scoring -= p5.deltaTime
      console.log("collide 2")
      game_direction_flag = -game_direction_flag;
      game_direction_vol = 0;
      basket_pos = p5.random(p5.height / 3, p5.height / 3 * 2);
      game_score += 1;
      return
      // this.vy = 0;
    } else {
      // if (scoring < 0) scoring = 1000;
      // let dx = spirit.x - this.x;
      // let dy = spirit.y - this.y;
      // let distance = p5.sqrt(dx * dx + dy * dy);
      // let minDist = spirit.width / 2 + this.diameter / 2;
      //
      // if (distance < minDist) {
      //   let angle = p5.atan2(dy, dx);
      //   let targetX = this.x + p5.cos(angle) * minDist;
      //   let targetY = this.y + p5.sin(angle) * minDist;
      //   let ax = (targetX - spirit.x) * spring;
      //   let ay = (targetY - spirit.y) * spring;
      //   this.vx -= ax;
      //   this.vy -= ay;
      // }
    }

    // console.log(oTop, oRight, oBottom, oLeft,)
    // console.log(this.x, this.y, this.diameter)


  }

  move(p5, dx, dy) {

    // this.vy = (this.vy < -6 || this.vy > 6) ? this.vy : this.vy + gravity + dy;

    this.x = p5.mouseX;
    this.y = p5.mouseY;

    // if (dy) this.vy = 0, this.vx = 0;
    // this.vy += gravity + dy;
    // this.x += (this.vx + dx);
    // this.y += (this.vy);
    //
    //
    // if (this.y + this.diameter > p5.height) {
    //   this.y = p5.height - this.diameter;
    //   this.vy *= friction;
    // } else if (this.y < -this.diameter) {
    //   this.y = -this.diameter;
    //   this.vy *= friction;
    // }
    //
    // if (this.x < -this.diameter) {
    //   this.x = p5.width;
    // } else if (this.x > p5.width) {
    //   this.x = -this.diameter;
    // }
  }

  display(p5, angle) {
    p5.push();
    p5.translate(this.x + this.diameter / 2, this.y + this.diameter / 2);
    p5.rotate(this.x + Math.abs(this.vy));
    p5.image(
      spirit_ball.src,
      0, 0,
      spirit_ball.width,
      spirit_ball.height,
    );
    p5.pop()
  }
}

class Basket {
  constructor(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.width = w;
    this.height = h;
    this.diameter = w;
  }

  move(p5, dx, dy) {
    let x = game_direction_flag > 0 ? p5.width - this.width : 0;
    this.x = x;
    this.y = basket_pos;
  }

  display(p5, x) {

    // p5.rectMode(p5.CENTER)
    p5.rect(this.x, basket_pos, this.width, this.height);
    // p5.image(
    //   spirit_basket.src,
    //   p5.width / 2,
    //   p5.height - (p5.width / 3 / 2) - spirit_battery.height * 2,
    //   p5.width,
    //   p5.width / 3,
    // );
  }
}